package com.wctj.api.business.common.service.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wctj.api.base.entity.DdwxPaymentMessageInfo;
import com.wctj.api.base.enums.ApiCode;
import com.wctj.api.base.exception.CustomException;
import com.wctj.api.base.utils.JacksonUtil;
import com.wctj.api.business.common.dto.DdwxPaymentMessageInfoDTO;
import com.wctj.api.business.common.service.DdwxPaymentMessageInfoService;
import com.wctj.api.business.common.service.EventTypeResponse;
import com.wctj.api.infra.common.bean.NoticeParams;
import com.wctj.api.infra.common.bean.NoticeRequest;
import com.wctj.api.infra.common.util.IOUtils;
import com.wctj.api.infra.common.util.sign.SignMd5Utils;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;

/**
 * CMB 支付回调响应模式处理
 */
@Slf4j
public abstract class CmbAbstractEventTypeResponse implements EventTypeResponse {

    @Resource
    protected DdwxPaymentMessageInfoService ddwxPaymentMessageInfoService;

    private static final String key = "UVIUODIBDU708";  //MD5密钥

    protected void updateMessage(String orderNo, int status, int pushStatus, LocalDateTime pushTime, String noticeBodyJsonStr) {
        DdwxPaymentMessageInfoDTO msgInfo = ddwxPaymentMessageInfoService.findByPayOrderNumber(orderNo);
        DdwxPaymentMessageInfoDTO ddwxPaymentMessageInfoDTO = new DdwxPaymentMessageInfoDTO(msgInfo.getId(), pushStatus, pushTime);
        ddwxPaymentMessageInfoDTO.setPushMsg(noticeBodyJsonStr);
        ddwxPaymentMessageInfoDTO.setStatus(status);
        ddwxPaymentMessageInfoService.updateById(ddwxPaymentMessageInfoDTO);
    }

    @Override
    public <P extends NoticeParams> P getNoticeParams(NoticeRequest request) {
        NoticeParams noticeParams = new NoticeParams();
        try (InputStream is = request.getInputStream()) {
            String body = IOUtils.toString(is);
            noticeParams.setBodyStr(body);
            noticeParams.setBody(JacksonUtil.parse(body,Map.class));
        } catch (IOException e) {
            throw new CustomException(ApiCode.PAY_CALLBACK_PARAM_ERROR, e);
        }
        Map<String, List<String>> headers = new HashMap<>();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            headers.put(name, Collections.list(request.getHeaders(name)));
        }
        noticeParams.setHeaders(headers);
        return (P) noticeParams;
    }



    protected Boolean saveMessage(DdwxPaymentMessageInfoDTO infoDTO) {
        // message db
        DdwxPaymentMessageInfo msgInfo = new DdwxPaymentMessageInfo();
        msgInfo.setBizCode(infoDTO.getBizCode());
        msgInfo.setPayOrderNum(infoDTO.getPayOrderNum());
        msgInfo.setPushStatus(infoDTO.getPushStatus());
        msgInfo.setStatus(infoDTO.getStatus());
        msgInfo.setVersion(0);
        msgInfo.setPushRetryCnt(0);
        msgInfo.setNotifyUrl(infoDTO.getNotifyUrl());
        //msgInfo.setRequestBody(infoDTO.getRequestBody());
        //msgInfo.setResponseMsg(infoDTO.getResponseMsg());
        msgInfo.setEventType(infoDTO.getEventType());
        msgInfo.setPlatform(infoDTO.getPlatform());
        return ddwxPaymentMessageInfoService.save(msgInfo);
    }

    protected String addRequestSignature(String noticeBodyJsonStr) {
        // jsonString转换成Map
        /*Map<String, String> jsonMap = JSON.parseObject(noticeBodyJsonStr, new TypeReference<HashMap<String, String>>() {
        });*/
        Map jsonMap =JacksonUtil.parse(noticeBodyJsonStr,Map.class);
        Map<String,String> lastMap = changeString(jsonMap);
        //System.out.println(jsonMap.toString());
        SignMd5Utils signMd5Utils = new SignMd5Utils();
        log.info("cmb notify post Map：{}", lastMap.toString());
        String sign = signMd5Utils.createSign(lastMap, key, "UTF-8");
        lastMap.put("sign",sign);
        log.info("cmb notify post sign：{}", sign);
        return JacksonUtil.getNormalPatternJsonString(lastMap);
    }

    public static Map<String, String> changeString(Map<String,Object> map){
        try {
            Map<String, String> resMap = new HashMap<>();
            for (Map.Entry<String, Object> entry: map.entrySet()) {
                String key1 = entry.getKey();
                Object obj = entry.getValue();
                //新建一个 ObjectMapper 对象
                ObjectMapper objectMapper = new ObjectMapper();
                if (obj instanceof String) {
                    resMap.put(key1, obj.toString());
                    continue;
                }
                String value = objectMapper.writeValueAsString(obj);
                resMap.put(key1, value);
            }
            return resMap;
        } catch (Exception e) {
            log.error("CmbAbstractEventTypeResponse Map error", e);
        }
        return null;
    }


}